import { isObject } from "../utils/index";
import {
  readonlyHandler,
  mutablehandler,
  shallowReadonlyhandler,
} from "./baseHandlers";

import { isRef } from "./ref";

export const enum ReactiveFlags {
  IS_READONLY = "__v_isReadonly",
  IS_REACTIVE = "__v_isReative",
  IS_REF = "__v_isRef",
  RAW = "__v_raw",
}

export const reactiveMap = new WeakMap();
export const readonlyMap = new WeakMap();
export const shallowReadonlyMap = new WeakMap();

export function reactive(target) {
  return createReactiveObject(target, reactiveMap, mutablehandler);
}

export function readonly(target) {
  return createReactiveObject(target, readonlyMap, readonlyHandler);
}

export function shallowReadonly(target) {
  return createReactiveObject(
    target,
    shallowReadonlyMap,
    shallowReadonlyhandler
  );
}

export function isProxy(target) {
  // 其实就是检测对象上是否存在特定的key
  return isReactive(target) || isReadonly(target) || isRef(target);
}

export function isReadonly(target) {
  // 其实就是检测对象上是否存在特定的key
  return !!target[ReactiveFlags.IS_READONLY];
}

export function isReactive(target) {
  // 其实就是检测对象上是否存在特定的key
  return !!target[ReactiveFlags.IS_REACTIVE];
}

export function toRaw(target) {
  // 先尝试从target取值,如果能继续获取到值,继续
  // 否则返回传入的参数
  const raw = target && target[ReactiveFlags.RAW];
  return raw ? toRaw(raw) : target;
}

function createReactiveObject(target, proxyMap, baseHandles) {
  // 如果传入的参数不是对象类型,那么就不用处理啦=了
  if (!isObject(target)) {
    return target;
  }

  // 缓存优化
  const existingProxy = proxyMap.get(target);
  if (existingProxy) {
    return existingProxy;
  }

  // 将传入的对象使用proxy代理
  const proxyTarget = new Proxy(target, baseHandles);
  proxyMap.set(target, proxyTarget);
  return proxyTarget;
}
